package service

import (
	"errors"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"guns-go/global"
	"guns-go/model"
	"guns-go/model/request"
	"guns-go/model/response"
	"guns-go/utils"
)

func QuerySysAppById(appId int) (err error, sysApp *model.SysApp) {
	var app *model.SysApp
	err = global.GVA_DB.Where("id = ?", appId).Find(&app).Error
	return err, app
}

func CreateSysApp(app *model.SysApp, tx *gorm.DB) error {
	return tx.Create(app).Error
}

func UpdateSysApp(app *model.SysApp, tx *gorm.DB) error {
	return tx.Model(&app).Updates(app).Error
}

func UpdateSysAppById(id int, active string, tx *gorm.DB) error {
	return tx.Model(model.SysApp{}).Where("id = ?", id).Update("active", active).Error
}

func GetLoginApps(userId int) (err error, apps []map[string]interface{}) {

	appSlice := make([]map[string]interface{}, 0)

	var appS []model.SysApp
	db := global.GVA_DB.Where("status = ?", 0)

	//查询sysUser
	err, sysUser := QueryUserById(userId)

	if err != nil {
		return err, nil
	}

	adminType := sysUser.AdminType

	//如果不是超级管理员则有自己的菜单对应的应用编码
	if adminType != global.SuperAdmin {

		//获取用户菜单对应的应用编码集合
		err, appCodes := GetUserMenuAppCodeList(userId)

		if err != nil {
			return err, nil
		}

		if len(appCodes) > 0 {
			db = db.Where("code in(?)", appCodes)
		} else {
			return err, appSlice
		}
	}

	hasDefaultActive := false

	err = db.Find(&appS).Error

	if err != nil {
		return err, nil
	}

	if len(appS) > 0 {
		for _, app := range appS {
			dict := make(map[string]interface{}, 0)
			dict[global.CODE] = app.Code
			dict[global.NAME] = app.Name

			if app.Active == global.Y {
				hasDefaultActive = true
				dict["active"] = true
				appSlice = append(appSlice, dict)
			} else {
				dict["active"] = false
				appSlice = append(appSlice, dict)
			}
		}

		if len(appSlice) > 0 {
			//如果默认激活的系统没有，则第一个为默认激活的系统
			if !hasDefaultActive {
				dict := appSlice[0]
				dict["active"] = true
			}
		}
	}
	return err, appSlice
}
func AppPage(sysAppParam *request.SysAppParam, c *gin.Context) (err error, result *response.PageResult) {

	var sysAppSlice []*model.SysApp
	db := global.GVA_DB

	if sysAppParam != nil {

		//根据名称模糊查询
		if sysAppParam.Name != "" {
			db = db.Where("name like ?", "%"+sysAppParam.Name+"%")
		}

		//根据编码模糊查询
		if sysAppParam.Code != "" {
			db = db.Where("code like ?", "%"+sysAppParam.Code+"%")
		}
	}

	db = db.Where("status = ?", 0)

	var totalCount int64

	err = db.Find(&sysAppSlice).Count(&totalCount).Error

	if err != nil {
		return err, nil
	}

	pageNo, pageSize, db := utils.DefaultPage(c, db)

	err = db.Find(&sysAppSlice).Error

	if err != nil {
		return err, nil
	}

	return err, utils.CoverToPageResult(pageNo, pageSize, totalCount, sysAppSlice)
}

func AppAdd(sysAppParam *request.SysAppParam) error {

	//校验参数，检查是否存在相同的名称和编码，以及默认激活的系统的数量是否合理
	err := checkParamByApp(sysAppParam, false)

	if err != nil {
		return err
	}

	sysApp := new(model.SysApp)

	err = utils.SimpleCopyProperties(sysApp, sysAppParam)

	if err != nil {
		return err
	}

	var zero int8
	zero = 0

	sysApp.Status = &zero

	tx := global.GVA_DB.Begin()
	err = CreateSysApp(sysApp, tx)

	if err != nil {
		tx.Rollback()
		return err
	}
	tx.Commit()
	return nil
}

func AppEdit(sysAppParam *request.SysAppParam) error {

	err, sysApp := QuerySysAppById(sysAppParam.Id)

	if err != nil {
		return err
	}

	if sysApp.Id == 0 {
		return errors.New("应用不存在")
	}

	//校验参数，检查是否存在相同的名称和编码，以及默认激活的系统的数量是否合理
	err = checkParamByApp(sysAppParam, true)

	if err != nil {
		return err
	}

	err = utils.SimpleCopyProperties(sysApp, sysAppParam)

	if err != nil {
		return err
	}

	sysApp.Status = nil

	tx := global.GVA_DB.Begin()
	err = UpdateSysApp(sysApp, tx)

	if err != nil {
		tx.Rollback()
		return err
	}
	tx.Commit()
	return nil
}

func AppDelete(sysAppParam *request.SysAppParam) error {

	err, sysApp := QuerySysAppById(sysAppParam.Id)

	if err != nil {
		return err
	}

	if sysApp.Id == 0 {
		return errors.New("应用不存在")
	}

	code := sysApp.Code

	//该应用下是否有状态为正常的菜单
	err, hasMenu := HasMenu(code)

	if err != nil {
		return err
	}

	if hasMenu {
		return errors.New("该应用下有菜单，无法删除")
	}

	var two int8
	two = 2

	sysApp.Status = &two

	tx := global.GVA_DB.Begin()
	err = UpdateSysApp(sysApp, tx)

	if err != nil {
		tx.Rollback()
		return err
	}
	tx.Commit()
	return nil
}

func SetAsDefault(sysAppParam *request.SysAppParam) error {

	err, sysApp := QuerySysAppById(sysAppParam.Id)

	if err != nil {
		return err
	}

	if sysApp.Id == 0 {
		return errors.New("应用不存在")
	}

	//所有已激活的改为未激活
	var sysAppSlice []*model.SysApp
	err = global.GVA_DB.Where("status = ?", 0).Where("active = ?", global.Y).Find(&sysAppSlice).Error

	if err != nil {
		return err
	}

	tx := global.GVA_DB.Begin()

	if len(sysAppSlice) > 0 {
		for _, app := range sysAppSlice {
			err = UpdateSysAppById(app.Id, global.N, tx)

			if err != nil {
				tx.Rollback()
				return err
			}
		}
	}

	//当前的设置为已激活
	err = UpdateSysAppById(sysApp.Id, global.Y, tx)

	if err != nil {
		tx.Rollback()
		return err
	}
	tx.Commit()
	return nil
}

//校验参数，检查是否存在相同的名称和编码，以及默认激活的系统的数量是否合理
func checkParamByApp(sysAppParam *request.SysAppParam, isExcludeSelf bool) error {

	id := sysAppParam.Id
	name := sysAppParam.Name
	code := sysAppParam.Code
	active := sysAppParam.Active

	var sysAppSlice []*model.SysApp

	db := global.GVA_DB
	// 查询名称有无重复
	dbName := db.Where("name = ?", name).Where("status <> ?", 2)
	// 查询编码有无重复
	dbCode := db.Where("code = ?", code).Where("status <> ?", 2)
	// 查询激活状态有无已经有Y的，也就是激活的
	dbCodeActive := db.Where("active = ?", active).Where("status <> ?", 2)

	if isExcludeSelf {
		dbName = dbName.Where("id <> ?", id)
		dbCode = dbCode.Where("id <> ?", id)
		dbCodeActive = dbCodeActive.Where("id <> ?", id)
	}

	var countByName int64
	err := dbName.Find(&sysAppSlice).Count(&countByName).Error

	if err != nil {
		return err
	}

	var countByCode int64
	err = dbCode.Find(&sysAppSlice).Count(&countByCode).Error

	if err != nil {
		return err
	}

	var countByActive int64
	err = dbCodeActive.Find(&sysAppSlice).Count(&countByActive).Error

	if err != nil {
		return err
	}

	if countByName >= 1 {
		return errors.New("应用名称重复，请检查name参数")
	}

	if countByCode >= 1 {
		return errors.New("应用编码重复，请检查code参数")
	}

	// 只判断激活状态为Y时候数量是否大于1了
	if countByActive >= 1 && global.Y == sysAppParam.Active {
		return errors.New("默认激活的系统只能有一个，请检查active参数")
	}

	return nil
}

func AppList() (error, []*model.SysApp) {

	var sysAppSlice []*model.SysApp
	err := global.GVA_DB.Where("status = ?", 0).Find(&sysAppSlice).Error

	if err != nil {
		return err, nil
	}

	if len(sysAppSlice) > 0 {
		return nil, sysAppSlice
	}
	return nil, make([]*model.SysApp, 0)
}
